package utils;

import java.io.*;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Utils {
    /**
     * 正则表达式处理函数，根据pattern提取出input中第一个满足要求的字符串
     *
     * @param input   待匹配字符串
     * @param pattern 匹配模板
     * @return 满足要求的字符串
     */
    public static String RegularExpressionProcess(String input, String pattern) {
        // 创建一个 Pattern 对象
        Pattern compiledPattern = Pattern.compile(pattern);
        // 使用 Pattern 对象创建一个 Matcher 对象
        Matcher matcher = compiledPattern.matcher(input);
        // 查找第一个匹配的子序列
        if (matcher.find()) {
            String matchStr = matcher.group(1);
            return matchStr;
        }
        return null;
    }


    /**
     * 正则表达式处理函数，判断input中能不能找到pattern模式的字符串
     *
     * @param input   待匹配字符串
     * @param pattern 匹配模板
     * @return true表示input中能找到满足pattern的字符串
     */
    public static boolean isInputContainsPattern(String input, String pattern) {
        // 创建一个 Pattern 对象
        Pattern compiledPattern = Pattern.compile(pattern);
        // 使用 Pattern 对象创建一个 Matcher 对象
        Matcher matcher = compiledPattern.matcher(input);
        // 查找第一个匹配的子序列
        if (matcher.find()) {
            return true;
        }
        return false;
    }

    /**
     * append一行字符串到目标文件
     *
     * @param line        字符串内容
     * @param dstFilePath 目标文件所在路径
     */
    public static void writeLineToDstFile(String line, String dstFilePath) {
        // 创建File对象
        File file = new File(dstFilePath);
        // 获取文件的父目录
        File parentDirectory = file.getParentFile();
        // 如果父目录不存在，则创建父目录
        if (!parentDirectory.exists()) {
            parentDirectory.mkdirs();
        }
        // 将line写入目标文件路径
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(dstFilePath, true))) {
            writer.write(line + "\n");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /** 判断两个文件中的内容是否完全相同
     * @param file1Path
     * @param file2Path
     * @return 如果相同则返回true
     * @throws FileNotFoundException
     */
    public static boolean isTwoFileEqual(String file1Path, String file2Path) throws FileNotFoundException {
        Scanner scanner1 = new Scanner(new FileReader(file1Path));
        Scanner scanner2 = new Scanner(new FileReader(file2Path));
        while (scanner2.hasNextLine()) {
            String line1 = scanner1.nextLine();
            String line2 = scanner2.nextLine();
            if (!line2.equals(line1)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 判断一个给定路径的文件是否存在
     * @param path 待判断的文件路径
     * @return
     */
    public static boolean isFileExsit(String path) {
        File file = new File(path);
        if (file.exists()) {
            return true;
        } else {
            return false;
        }
    }


    /**
     * 如果目标路径文件夹存在，则删除
     *
     * @param dstFolderPath 目标文件夹的路径
     */
    public static void deleteExsitDstFolder(String dstFolderPath) {
        // 创建File对象
        File directory = new File(dstFolderPath);
        if (directory.exists()) {
            // 删除目录及其所有内容
            if (deleteDirectoryHelper(directory)) {
                System.out.println(dstFolderPath + "目录已成功删除");
            } else {
                System.out.println("删除" + dstFolderPath + "目录失败");
            }
        }
    }
    public static boolean deleteDirectoryHelper(File directory) {
        if (!directory.exists()) {
            return false;
        }

        // 如果是目录，递归删除所有子文件和子目录
        if (directory.isDirectory()) {
            File[] files = directory.listFiles();
            if (files != null) { // 防止空指针异常
                for (File file : files) {
                    deleteDirectoryHelper(file);
                }
            }
        }

        // 最后删除目录本身或文件
        return directory.delete();
    }
    /**
     * 将源文件的所有内容 append 到 目标文件中
     * @param sourceFilePath 源文件所在的路径
     * @param targetFilePath 目标文件所在的路径
     */
    public static void mergeFiles(String sourceFilePath, String targetFilePath) {
        File sourceFile = new File(sourceFilePath);
        File targetFile = new File(targetFilePath);

        // 创建FileReader和FileWriter对象
        try (BufferedReader reader = new BufferedReader(new FileReader(sourceFile));
             BufferedWriter writer = new BufferedWriter(new FileWriter(targetFile, true))) {

            // 读取源文件并写入目标文件
            String line;
            while ((line = reader.readLine()) != null) {
                writer.write(line);
                writer.newLine();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获得当前行trace操作的名称
     * 例如 [106.241s][info][gc,heap     ] Return H:NULL, C:NULL, T:main, M:Student.<init> ()V 返回 Return
     * @param line 待处理的trace行
     * @return trace的操作名称
     */
    public static String getTraceOperationName(String line) {
        // 获得当前行trace的操作名称
        String currentLineComand = Utils.RegularExpressionProcess(line, "\\[gc,heap\\s+\\] (.*?) (H|H1):");
        if (currentLineComand == null) {
            // 有可能为NewM, 处理NewM C:[[Ljava/lang/invoke/LambdaForm$Name;, D:5 10 , T:main, M:java/lang/invoke/LambdaForm.<clinit> ()V
            String newMClassName = Utils.RegularExpressionProcess(line, "\\[gc,heap\\s+\\] NewM C:(.*?),"); // 获得NewM中的Class名称
            if (newMClassName != null) {
                // 表示这行语句是NewM
                currentLineComand = "NewM";
            }
        }
        return currentLineComand;
    }

}
